#include "responsivefilelistengine.h"
#include <QApplication>
#include <QPalette>
#include <QFontMetrics>
#include <QDebug>
#include <QPainter>
#include <QStyleOption>
#include <cmath>

using namespace SonyIveDesign;

// === AdaptiveTextProcessor 实现 ===

QString AdaptiveTextProcessor::getSmartEllipsis(const QString& text, int maxWidth, const QFont& font)
{
    QFontMetrics metrics(font);

    if (metrics.horizontalAdvance(text) <= maxWidth) {
        return text;
    }

    // 智能省略策略：优先保留文件名前半部分和扩展名
    QString baseName = text;
    QString extension;

    int dotIndex = text.lastIndexOf('.');
    if (dotIndex > 0) {
        baseName = text.left(dotIndex);
        extension = text.mid(dotIndex);
    }

    // 计算扩展名宽度
    int extensionWidth = metrics.horizontalAdvance(extension);
    int ellipsisWidth = metrics.horizontalAdvance("...");
    int availableWidth = maxWidth - extensionWidth - ellipsisWidth;

    if (availableWidth <= 0) {
        return "...";
    }

    // 逐字符缩减直到适合
    QString truncated = baseName;
    while (metrics.horizontalAdvance(truncated) > availableWidth && !truncated.isEmpty()) {
        truncated.chop(1);
    }

    return truncated + "..." + extension;
}

QString AdaptiveTextProcessor::getFileNameWithoutExtension(const QString& fileName, DisplayMode mode)
{
    if (mode == DisplayMode::Full || mode == DisplayMode::Expanded) {
        return fileName; // 保留完整文件名
    }

    int dotIndex = fileName.lastIndexOf('.');
    if (dotIndex > 0) {
        return fileName.left(dotIndex);
    }

    return fileName;
}

QFont AdaptiveTextProcessor::getAdaptiveFont(DisplayMode mode, bool isBold)
{
    QFont font = QApplication::font();

    switch (mode) {
        case DisplayMode::Micro:
            font.setPointSize(font.pointSize() - 2);
            break;
        case DisplayMode::Compact:
            font.setPointSize(font.pointSize() - 1);
            break;
        case DisplayMode::Standard:
            // 使用默认字体大小
            break;
        case DisplayMode::Expanded:
        case DisplayMode::Full:
            font.setPointSize(font.pointSize() + 1);
            break;
    }

    font.setBold(isBold);
    return font;
}

int AdaptiveTextProcessor::calculateTextWidth(const QString& text, const QFont& font)
{
    QFontMetrics metrics(font);
    return metrics.horizontalAdvance(text);
}

// === SonyColorPalette 实现 ===

QLinearGradient SonyColorPalette::createSonyGradient(const QRect& rect, bool isSelected, bool isHovered)
{
    QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());

    if (isSelected) {
        // Sony选中状态：蓝色渐变
        gradient.setColorAt(0.0, QColor(64, 128, 255, 40));
        gradient.setColorAt(0.5, QColor(96, 144, 255, 30));
        gradient.setColorAt(1.0, QColor(128, 160, 255, 20));
    } else if (isHovered) {
        // Sony悬停状态：温暖灰色渐变
        gradient.setColorAt(0.0, QColor(240, 240, 240, 60));
        gradient.setColorAt(0.5, QColor(245, 245, 245, 40));
        gradient.setColorAt(1.0, QColor(250, 250, 250, 20));
    } else {
        // Sony正常状态：微妙渐变
        gradient.setColorAt(0.0, QColor(255, 255, 255, 20));
        gradient.setColorAt(0.5, QColor(250, 250, 250, 15));
        gradient.setColorAt(1.0, QColor(245, 245, 245, 10));
    }

    return gradient;
}

QColor SonyColorPalette::getStatusColor(FileProcessStatus status, double opacity)
{
    QColor color;

    switch (status) {
        case FileProcessStatus::Waiting:
            color = QColor(156, 163, 175); // 灰色
            break;
        case FileProcessStatus::Processing:
            color = QColor(59, 130, 246); // 蓝色
            break;
        case FileProcessStatus::Completed:
            color = QColor(34, 197, 94); // 绿色
            break;
        case FileProcessStatus::Error:
            color = QColor(239, 68, 68); // 红色
            break;
    }

    color.setAlphaF(opacity);
    return color;
}

QColor SonyColorPalette::getTextColor(bool isPrimary, double opacity)
{
    QPalette palette = QApplication::palette();
    QColor color = isPrimary ? palette.color(QPalette::Text) : palette.color(QPalette::Mid);
    color.setAlphaF(opacity);
    return color;
}

QColor SonyColorPalette::getBorderColor(bool isSelected, double opacity)
{
    QColor color = isSelected ? QColor(59, 130, 246) : QColor(156, 163, 175);
    color.setAlphaF(opacity);
    return color;
}

QColor SonyColorPalette::getShadowColor(double opacity)
{
    QColor color = QColor(0, 0, 0);
    color.setAlphaF(opacity);
    return color;
}

// === ResponsiveFileListEngine 实现 ===

ResponsiveFileListEngine::ResponsiveFileListEngine(QWidget* parentWidget)
    : QObject(parentWidget)
    , m_parentWidget(parentWidget)
    , m_currentDisplayMode(DisplayMode::Standard)
    , m_targetDisplayMode(DisplayMode::Standard)
    , m_animationOpacity(1.0)
    , m_hoverScale(1.0)
    , m_selectionScale(1.0)
    , m_isTransitioning(false)
    , m_lastContainerWidth(0)
    , m_isPerformanceModeEnabled(false)
{
    initializeAnimationSystem();
    setupPerformanceTimer();
    createDropShadowEffect();
}

DisplayMode ResponsiveFileListEngine::calculateDisplayMode(int containerWidth) const
{
    if (containerWidth < DesignConstants::BREAKPOINT_MICRO) {
        return DisplayMode::Micro;
    } else if (containerWidth < DesignConstants::BREAKPOINT_COMPACT) {
        return DisplayMode::Compact;
    } else if (containerWidth < DesignConstants::BREAKPOINT_STANDARD) {
        return DisplayMode::Standard;
    } else if (containerWidth < DesignConstants::BREAKPOINT_EXPANDED) {
        return DisplayMode::Expanded;
    } else {
        return DisplayMode::Full;
    }
}

int ResponsiveFileListEngine::calculateOptimalColumns(int containerWidth) const
{
    DisplayMode mode = calculateDisplayMode(containerWidth);
    QSize itemSize = calculateItemSize(mode);

    if (itemSize.width() <= 0) {
        return 1;
    }

    // 考虑间距的列数计算
    int spacing = DesignConstants::SPACING_NORMAL;
    int availableWidth = containerWidth - spacing;
    int columns = std::max(1, availableWidth / (itemSize.width() + spacing));

    // 限制最大列数以保持可读性
    return std::min(columns, 6);
}

int ResponsiveFileListEngine::calculateItemHeight(DisplayMode mode) const
{
    switch (mode) {
        case DisplayMode::Micro:
            return 32;
        case DisplayMode::Compact:
            return 40;
        case DisplayMode::Standard:
            return 48;
        case DisplayMode::Expanded:
            return 56;
        case DisplayMode::Full:
            return 64;
    }
    return 48;
}

QSize ResponsiveFileListEngine::calculateItemSize(DisplayMode mode) const
{
    int height = calculateItemHeight(mode);
    int width;

    switch (mode) {
        case DisplayMode::Micro:
            width = 140;
            break;
        case DisplayMode::Compact:
            width = 200;
            break;
        case DisplayMode::Standard:
            width = 280;
            break;
        case DisplayMode::Expanded:
            width = 380;
            break;
        case DisplayMode::Full:
            width = 480;
            break;
    }

    return QSize(width, height);
}

void ResponsiveFileListEngine::animateToDisplayMode(DisplayMode newMode)
{
    if (m_currentDisplayMode == newMode || m_isTransitioning) {
        return;
    }


    m_targetDisplayMode = newMode;
    m_isTransitioning = true;

    // 创建模式切换动画
    m_opacityAnimation->setStartValue(1.0);
    m_opacityAnimation->setEndValue(0.3);
    m_opacityAnimation->setDuration(DesignConstants::ANIMATION_DURATION_FAST);

    connect(m_opacityAnimation, &QPropertyAnimation::finished,
            this, &ResponsiveFileListEngine::onModeTransitionFinished,
            Qt::UniqueConnection);

    m_opacityAnimation->start();
}

void ResponsiveFileListEngine::animateHoverEffect(QWidget* target, bool isHovering)
{
    if (!target || m_isPerformanceModeEnabled) {
        return;
    }

    m_hoverAnimation->setTargetObject(this);
    m_hoverAnimation->setPropertyName("hoverScale");
    m_hoverAnimation->setStartValue(m_hoverScale);
    m_hoverAnimation->setEndValue(isHovering ? DesignConstants::HOVER_SCALE : 1.0);
    m_hoverAnimation->setDuration(DesignConstants::ANIMATION_DURATION_FAST);
    m_hoverAnimation->setEasingCurve(QEasingCurve::OutCubic);

    m_hoverAnimation->start();
}

void ResponsiveFileListEngine::animateSelectionEffect(QWidget* target, bool isSelected)
{
    if (!target || m_isPerformanceModeEnabled) {
        return;
    }

    m_selectionAnimation->setTargetObject(this);
    m_selectionAnimation->setPropertyName("selectionScale");
    m_selectionAnimation->setStartValue(m_selectionScale);
    m_selectionAnimation->setEndValue(isSelected ? DesignConstants::SELECTION_SCALE : 1.0);
    m_selectionAnimation->setDuration(DesignConstants::ANIMATION_DURATION_NORMAL);
    m_selectionAnimation->setEasingCurve(QEasingCurve::OutCubic);

    m_selectionAnimation->start();
}

void ResponsiveFileListEngine::applySonyDropShadow(QWidget* target)
{
    if (!target || m_isPerformanceModeEnabled) {
        return;
    }

    auto* shadow = new QGraphicsDropShadowEffect(target);
    shadow->setBlurRadius(DesignConstants::SHADOW_BLUR_RADIUS);
    shadow->setOffset(DesignConstants::SHADOW_OFFSET, DesignConstants::SHADOW_OFFSET);
    shadow->setColor(SonyColorPalette::getShadowColor(0.3));

    target->setGraphicsEffect(shadow);
}

void ResponsiveFileListEngine::removeSonyDropShadow(QWidget* target)
{
    if (target && target->graphicsEffect()) {
        target->setGraphicsEffect(nullptr);
    }
}

QPixmap ResponsiveFileListEngine::createSonyBackgroundTexture(const QSize& size, bool isSelected, bool isHovered)
{
    QString cacheKey = QString("%1x%2_%3_%4")
                      .arg(size.width())
                      .arg(size.height())
                      .arg(isSelected ? "sel" : "norm")
                      .arg(isHovered ? "hov" : "reg");

    if (m_backgroundCache.contains(cacheKey)) {
        return m_backgroundCache[cacheKey];
    }

    QPixmap pixmap(size);
    pixmap.fill(Qt::transparent);

    QPainter painter(&pixmap);
    painter.setRenderHint(QPainter::Antialiasing);

    QRect rect(0, 0, size.width(), size.height());
    QLinearGradient gradient = SonyColorPalette::createSonyGradient(rect, isSelected, isHovered);

    painter.setBrush(QBrush(gradient));
    painter.setPen(QPen(SonyColorPalette::getBorderColor(isSelected, 0.5), 1));
    painter.drawRoundedRect(rect.adjusted(1, 1, -1, -1), DesignConstants::BORDER_RADIUS, DesignConstants::BORDER_RADIUS);

    m_backgroundCache[cacheKey] = pixmap;
    return pixmap;
}

void ResponsiveFileListEngine::enablePerformanceMode(bool enabled)
{
    m_isPerformanceModeEnabled = enabled;
}

void ResponsiveFileListEngine::clearCache()
{
    m_backgroundCache.clear();
}

void ResponsiveFileListEngine::setAnimationOpacity(double opacity)
{
    if (qAbs(m_animationOpacity - opacity) > 0.01) {
        m_animationOpacity = opacity;
        if (m_parentWidget) {
            m_parentWidget->update();
        }
    }
}

void ResponsiveFileListEngine::setHoverScale(double scale)
{
    if (qAbs(m_hoverScale - scale) > 0.01) {
        m_hoverScale = scale;
        if (m_parentWidget) {
            m_parentWidget->update();
        }
    }
}

void ResponsiveFileListEngine::setSelectionScale(double scale)
{
    if (qAbs(m_selectionScale - scale) > 0.01) {
        m_selectionScale = scale;
        if (m_parentWidget) {
            m_parentWidget->update();
        }
    }
}

void ResponsiveFileListEngine::onContainerResized(const QSize& newSize)
{
    int newWidth = newSize.width();

    if (qAbs(newWidth - m_lastContainerWidth) < 10) {
        return; // 忽略微小变化
    }

    m_lastContainerWidth = newWidth;
    DisplayMode newMode = calculateDisplayMode(newWidth);

    if (newMode != m_currentDisplayMode) {
        animateToDisplayMode(newMode);
    }
}

void ResponsiveFileListEngine::onThemeChanged()
{
    clearCache();
    if (m_parentWidget) {
        m_parentWidget->update();
    }
}

void ResponsiveFileListEngine::onModeTransitionFinished()
{
    if (m_targetDisplayMode != m_currentDisplayMode) {
        DisplayMode oldMode = m_currentDisplayMode;
        m_currentDisplayMode = m_targetDisplayMode;

        emit displayModeChanged(m_currentDisplayMode, oldMode);
        emit layoutUpdateRequired();

        // 恢复透明度
        m_opacityAnimation->setStartValue(0.3);
        m_opacityAnimation->setEndValue(1.0);
        m_opacityAnimation->start();
    }

    m_isTransitioning = false;
    emit animationFinished();
}

void ResponsiveFileListEngine::initializeAnimationSystem()
{
    m_opacityAnimation = new QPropertyAnimation(this, "animationOpacity", this);
    m_hoverAnimation = new QPropertyAnimation(this, "hoverScale", this);
    m_selectionAnimation = new QPropertyAnimation(this, "selectionScale", this);

    m_transitionGroup = new QParallelAnimationGroup(this);
    m_transitionGroup->addAnimation(m_opacityAnimation);
}

void ResponsiveFileListEngine::setupPerformanceTimer()
{
    m_performanceTimer = new QTimer(this);
    m_performanceTimer->setSingleShot(true);
    m_performanceTimer->setInterval(5000); // 5秒后启用性能模式

    connect(m_performanceTimer, &QTimer::timeout, this, [this]() {
        enablePerformanceMode(true);
    });
}

void ResponsiveFileListEngine::createDropShadowEffect()
{
    m_dropShadowEffect = new QGraphicsDropShadowEffect(this);
    m_dropShadowEffect->setBlurRadius(DesignConstants::SHADOW_BLUR_RADIUS);
    m_dropShadowEffect->setOffset(DesignConstants::SHADOW_OFFSET, DesignConstants::SHADOW_OFFSET);
    m_dropShadowEffect->setColor(SonyColorPalette::getShadowColor(0.2));
}